//生产环境下webpack的配置

const path = require('path');
//包体积分析工具
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //把css抽离成单独的一个文件
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); //压缩css
const TerserPlugin = require('terser-webpack-plugin'); //优化js压缩混淆速度

const config = {
  mode: 'production', //开发环境
  entry: './src/index.tsx', //入口文件
  output: {
    filename: '[name].[hash:8].js',
    path: path.join(__dirname, './dist'),
    publicPath: '/',
  }, //出口文件
  //路径解析规则
  resolve: {
    //配置别名
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], // 自动解析的扩展名
  },
  devtool: 'hidden-source-map',
  optimization: {
    //把chunk通用的代码抽离,优化包体积大小
    runtimeChunk: {
      name: 'runtime',
    },
    minimize: true, //启用压缩
    minimizer: [
      // 压缩css
      new CssMinimizerPlugin(),
      // 压缩js
      new TerserPlugin({
        parallel: true, // 开启多线程压缩
        terserOptions: {
          compress: {
            drop_console: true, // 删除console.log
          },
          output: {
            comments: false, //删除注释
          },
        },
        extractComments: false, //不提取注释到单独文件
      }),
    ],
    //代码分割
    splitChunks: {
      cacheGroups: {
        //提取node_modules代码
        vendor: {
          test: /node_modules/, //只匹配node_modules里面的模块
          name: 'vendors', //生成模块的名称
          minChunks: 1, //只要使用一次就提取出来
          chunks: 'initial', //只提取初始化就能获取到的模块,不管异步
          minSize: 0, //提取代码体积大于0就提取出来
          priority: 1, //提取优先级为1
        },
        //提取页面公共代码
        commons: {
          name: 'commons', //提取文件名为commons
          minChunks: 2, //只要使用一次就提取出来
          chunks: 'initial', //只提取初始化就能获取到的模块,不管异步
          minSize: 0, //提取代码体积大于0就提取出来
        },
      },
    },
  },
  //开启缓存优化
  cache: {
    type: 'filesystem', // 使用文件缓存
  },
  //使用插件
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new MiniCssExtractPlugin({
      //打包后CSS文件的名字
      filename: '[name].css', //输出的css文件名
      chunkFilename: '[id].css', //处理chunk文件名
    }),
    new BundleAnalyzerPlugin(),
  ],
  //模块加载规则  loader
  module: {
    rules: [
      {
        test: /\.(css|less)$/, // 基于正则匹配：哪些文件是我们需要处理的
        use: [
          MiniCssExtractPlugin.loader, // 提取css
          'css-loader', //处理特殊语法
          'postcss-loader', //配合autoprefixer&browserlist给css3属性设置前缀【兼容】
          'less-loader', //把less编译为css
        ],
        exclude: /\.module\.less$/,
      },
      {
        test: /\.module\.less$/i, // 基于正则匹配：哪些文件是我们需要处理的
        use: [
          'style-loader', // 将 CSS 插入到 DOM 中
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[name]__[local]___[hash:base64:5]', // CSS Modules 的类名格式
                namedExport: false, // 启用 CSS Modules 命名导出
              },
              sourceMap: true, // 启用 source maps（可选）
              importLoaders: 1,
            },
          },
          'less-loader', // 将 Less 编译为 CSS
        ],
      },
      {
        test: /\.js$/,
        use: ['babel-loader'],
        exclude: /node_modules/,
      },
      {
        test: /\.tsx?$/,
        use: {
          loader: 'ts-loader',
          options: {
            compilerOptions: {
              noEmit: false, // this option will solve the issue
            },
          },
        },
        exclude: /node_modules/,
      },
      {
        test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
        type: 'asset',
      },
    ],
  },
};
module.exports = config;
